/**
 * 
 */
package uk.ac.ebi.velvet.util.file;

import java.io.File;
import java.io.IOException;
import java.util.Collection;

import uk.ac.ebi.curtain.utils.file.FileInfo;
import uk.ac.ebi.curtain.utils.io.MultipleFileHandler;
import uk.ac.ebi.curtain.utils.io.MultipleFileHandler.FileAccess;
import uk.ac.ebi.curtain.utils.io.impl.BufferedRaf;
import uk.ac.ebi.curtain.utils.io.impl.FileIO;
import uk.ac.ebi.velvet.config.VelvetDataAccessService;

/**
 * NOT THREAD SAFE
 * 
 * @author mhaimel
 *
 */
public class GlobalRandomFileAccess {
//	private Map<File, Long> file2PosIdx = new HashMap<File, Long>();
	private MultipleFileHandler<BufferedRaf, File> fHanderl =
		new MultipleFileHandler<BufferedRaf, File>(new FileAccess<BufferedRaf>(){
			@Override
			public BufferedRaf openFile(File file) throws IOException {
				return new FileIO(file).getBufferedRafReader();
			}});
	
	private VelvetDataAccessService data;

	public GlobalRandomFileAccess(VelvetDataAccessService data) {
		this.data = data;
		init();
	}
	
	protected void init(){
		registerFileInfo(getData().getVelvetArgs().getContigFiles());
		registerFileInfo(getData().getVelvetArgs().getReadFiles());
		registerFileInfo(getData().getVelvetArgs().getShortPairedFiles());
	}
	
	public BufferedRaf getChannel(File info) throws IOException{
		return getChannelAt(getGlobalStartPosition(info));
	}
	
	public BufferedRaf getChannelAt(long globalPosition) throws IOException{
		FileInfo fInfo = getData().getFileForPosition(globalPosition);
		long localPos = getData().translate2LocalPosition(globalPosition);
		BufferedRaf channel = fHanderl.getChannel(fInfo.getFile());
		channel.seek(localPos);
		return channel;
	}
	
	public long translatePosition(File info, long position){
		long gPos = getGlobalStartPosition(info);
		return gPos + position;
	}
	
	public void registerFile(Collection<File> info){
		for(File f : info){
			registerFile(f);
		}
	}
	public void registerFileInfo(Collection<FileInfo> info){
		for(FileInfo f : info){
			registerFile(f.getFile());
		}
	}
	public void registerFile(File file){
			fHanderl.addFile(file,file);
	}
	
	public long getGlobalStartPosition(File info) {
		return getData().getGlobalFilePosition(info);
	}
	
	private VelvetDataAccessService getData() {
		return data;
	}

	public void close(File file){
		fHanderl.close(file);
	}
	public void close(Long globalPosition) {
		close(getData().getFileForPosition(globalPosition).getFile());
	}

	public void closeAll() {
		fHanderl.closeAll();
	}
	

}
